home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / DataStructs / hotsAccess.c next >
Encoding:
C/C++ Source or Header  |  1990-08-17  |  27.3 KB  |  897 lines

  1.  
  2. /*
  3.  * @(#)hotsAccess.c    1.3  2/23/90
  4.  */
  5.  
  6. /*
  7.  * $Header:   /u1/Eden/Kernel/DataStructs/hotsAccess.c Revision 3.3  85/03/11  19:04:23  eric  Exp$
  8.  * INTERFACE: This module is used by invoking the functions listed
  9.  *            below in the EXPORTS column.  The interface to each
  10.  *            procedure is described in the header comments of
  11.  *            the procedures themselves.
  12.  *            If the flag HOTSDBG is defined debug information is written
  13.  *            onto a file pointed to by stderr. 
  14.  * FUNCTION : Definition and operations on the data structure HOTS.
  15.  *            This module defines the data structure HOTS and implements
  16.  *            operations on it.  The operations provided are: creating the
  17.  *            data structure, creating an entry, inserting an entry, searching
  18.  *            for an entry, replacing an entry, and deleting an entry.
  19.  * IMPORTS  : PrintTS, PrintEdenPort, PrintNodeStatus, PrintNodeCharacteristics,
  20.  *            PrintNodeNum, and PrintEtherNetAddress.
  21.  * EXPORTS  : CreateHOTSRecord HOTSCreate   HOTSInsert      HOTSSearch
  22.  *            HOTSSearchPtr    HOTSReplace  HOTSDelete      PrintHOTSTable
  23.  *            PrintHOTS        HOTSTraverse Whatisup        HOTSDump
  24.  * SNAPSHOTS: A snapshot called Whatisup which prints the HOTS table in
  25.  *            a nice format indicating which machines are up.
  26.  *            A snapshot to dump the table in a readable format (or just one
  27.  *            entry): HOTSDump
  28.  * DESIGN   : A hash table representation is used for representing the
  29.  *            structure.  The hash table, HOTSTable, is organized as an 
  30.  *            array containing pointers.  Each entry in the table points 
  31.  *            to the head  of a list of records, HOTStr.  A record (called
  32.  *            HOTSRecord) in HOTStr contains the actual HOTS information.
  33.  *            The records in a list are those which hash to the same value.
  34.  *            Hash function used: (LNN & 2**LOGSIZE-1), where LNN is a logical
  35.  *            node number.
  36.  *            The algorithms used for inserting, deleting, searching, and
  37.  *            replacing are standard list algorithms.  The details are given
  38.  *            as comments with the individual procedures.
  39.  *            A one-item cache is used to improve efficiency.
  40.  * TO DO    : Should include the ability to search the structure for nodes
  41.  *            having certain characteristics.  
  42.  * $Log:    /u1/Eden/Kernel/DataStructs/hotsAccess.c $
  43.  * Revision 3.3  85/03/11  19:04:23  eric
  44.  * Minor improvements to HOTS Dump.
  45.  *
  46.  * Revision 3.2  84/11/29  19:04:23  schwartz
  47.  * Changed all calls to malloc so they don't call HoldSigs and ReleaseSigs
  48.  * before and after, since this is now done in (Almes' version of) malloc.
  49.  *
  50.  * Revision 3.1  84/11/19  15:01:15  schwartz
  51.  * Fixed KMD routines so they can print the names of any physical host, and
  52.  * so they know about NodeCharacteristics IsBrdcstProcess and IsEFTServer,
  53.  * and so that they correctly determine the default Nodes.
  54.  *
  55.  * Revision 3.0  84/07/04  00:04:02  schwartz
  56.  * Changes for port of Eden to Sun workstations.
  57.  *
  58.  * Revision 2.2  84/02/17  14:53:21  eric
  59.  * Fixed HOTSTraverse so that it responds correctly when HOTS table
  60.  * has not been initialized.
  61.  * 
  62.  * Revision 2.1  84/02/16  22:02:19  oystr
  63.  * Version 2 baseline.
  64.  * 
  65.  * Revision 1.10  84/02/16  13:46:16  eric
  66.  * Major revision of the Message Module requiring introduction of new
  67.  * fields on a per node basis in the HOTS table.
  68.  * 
  69.  * Revision 1.7  83/12/01  16:47:12  eric
  70.  * HOTSTraverse routine added by Jan Sanislo.
  71.  * It may be used to sequentially traverse the entries in the table.
  72.  * 
  73.  * Revision 1.6  83/08/07  20:40:31  venkat
  74.  * included decrementing NoHOTSEntries when a HOTS entry is deleted.
  75.  * 
  76.  * Revision 1.5  83/03/15  11:52:11  venkat
  77.  * Added a new function HOTSSearchPtr to return a pointer to a located HOTSRecord.
  78.  * 
  79.  * Revision 1.4  83/02/25  11:55:20  venkat
  80.  * PrintHOTSTable and PrintHOTS now return KKStatus.
  81.  * 
  82.  * Revision 1.3  83/01/26  11:51:29  venkat
  83.  * Changed the type of the argument for CreateHOTSRecord to a pointer to the
  84.  * pointer of a HOTSRecord.
  85.  * 
  86.  * Revision 1.2  83/01/08  11:50:57  venkat
  87.  * HOTSTable has now been declared as an array of size HOTSIZE instead of
  88.  * HOTSLIMIT - 1.
  89.  * 
  90.  * Revision 1.1  83/01/04  15:16:41  venkat
  91.  * Initial revision
  92.  * 
  93.  *
  94.  */
  95.  
  96.  
  97. #include <stdio.h>
  98. #include "Kernel/h/system.h"
  99. #include "Kernel/h/mmTypes.h"
  100. #include "Kernel/h/stdTypes.h"
  101. #include "Kernel/h/dstCodes.h"
  102. #include "Kernel/h/hotsTypes.h"
  103. #include "Kernel/h/edenBaseTime.h"
  104. #include "Kernel/h/kEvents.h"
  105. #include "Kernel/h/kmdTypes.h"
  106.  
  107. /* Forward declaration of snapshots and traces. */
  108. void SnapHOTSElem(), HOTSDump(), Whatisup();
  109.  
  110.  
  111.  
  112. /* For printing Nodestatus: */
  113. #define NSStatus(x) x == Dead ? "Dead" : x == Alive ? "Alive" : \
  114.     x == Deaf ? "Deaf" : x == Dumb ? "Dumb" : x == Booting ? "Booting" : \
  115.     "Unknown status"
  116.  
  117. #define  HOTSLAST  255          /* Must be HOTSIZE - 1 (addr of last)  */
  118. #define  HOTSLIMIT 250          /* Maximum number of HOTS entries      */
  119. #define  HashValue(lnn) (lnn & HOTSLAST)
  120.  
  121. /*Hash table as an array of pointers*/
  122. struct HOTStr *HOTSTable[HOTSIZE];
  123.  
  124. int NoHOTSEntries;                /*No. of entries in the HOTS table*/
  125. Boolean initflag = False;         /*Has HOTSCreate been called yet?*/ 
  126. static NodeNum CacheLNN = 0;      /*Cached LNN no. */
  127. static HOTSRecord *CachePtr;      /*Cached pointer.*/
  128. char *malloc();                   /*C function to allocate storage  */
  129.  
  130. extern PrintEdenPort(), PrintTS(), PrintNodeStatus(), PrintNodeCharacteristics();
  131. extern PrintNodeNum(), PrintEtherNetAddress();
  132.  
  133. KKStatus InsertInTable(), PrintHOTSTable(), PrintHOTS();
  134. KKStatus HOTSInsert(),HOTSCreate(),HOTSSearch(),HOTSReplace(),HOTSDelete();
  135. struct HOTStr *LookUp();
  136.  
  137. /*
  138.  * RETURNS     : KKStatus
  139.  * EFFECT      : Initializes HOTSTable, by setting the number of entries to
  140.  *               0 and the entries to NULL.  Also, sets the flag, initflag,
  141.  *               which is used by the other exported functions to check 
  142.  *               whether they are called without creating the HOTS table.
  143.  * DEFICIENCIES: Have not included any check to see whether sufficient memory
  144.  *               is available.
  145.  * INTERFACE   : HOTSCreate()
  146.  */    
  147.  
  148.  
  149. KKStatus HOTSCreate()
  150. {
  151.     int i;
  152.  
  153. #ifdef HOTSDBG
  154.     printf("entering HOTSCreate\n");
  155. #endif
  156.  
  157.     NoHOTSEntries = 0;
  158.     CacheLNN = 0;
  159.  
  160.     /*Initialize HOTSTable: set entries to null*/
  161.     for (i = 0; i <= HOTSLAST; ++i)
  162.         HOTSTable[i] = NULL;
  163.  
  164.     initflag = True;
  165.     
  166.     /* Set snapshots. */
  167.     KMDSetSnap(HOTSDump);
  168.     KMDSetSnap(Whatisup);
  169.  
  170. #ifdef HOTSDBG
  171.     printf("returning from HOTSCreate\n");
  172. #endif
  173.  
  174.     return(DSTS_Success);
  175. }
  176.  
  177.  
  178. /*
  179.  * OUT         : fNewRecord, a pointer to HOTSRecord
  180.  * RETURNS     : KKStatus
  181.  * EFFECT      : Creates a HOTSRecord entry and returns a pointer to it
  182.  *               in fNewRecord. 
  183.  * DEFICIENCIES: For now only storage is allocated for a HOTSRecord entry
  184.  *               and it is upto the caller to fill in the entries of the
  185.  *               HOTSRecord structure.
  186.  * INTERFACE   : CreateHOTSRecord(fNewRecord)
  187.  *               fNewRecord is a pointer to a pointer of HOTSRecord.
  188.  */
  189.  
  190. KKStatus CreateHOTSRecord(fNewRecord)
  191.     HOTSRecord **fNewRecord;
  192. {
  193.    (*fNewRecord) = (HOTSRecord *) malloc(sizeof(HOTSRecord));
  194.     if ((*fNewRecord) == NULL)
  195.         return(DSTK_NoMemory);
  196.     else
  197.         return(DSTS_Success);
  198. }
  199.  
  200.  
  201. /* 
  202.  * IN          : fNewNode
  203.  * RETURNS     : KKStatus
  204.  * EFFECT      : To insert a HOTSRecord entry into the hash table.  The entry
  205.  *               is inserted if it is not a duplicate and does not cause 
  206.  *               table overflow.  Invokes function InsertInTable to check for
  207.  *               duplicates and to insert if the given LNN is not a duplicate.
  208.  *               The LNN pointed to by fNewNode is hashed to get a table
  209.  *               index.  This gives a pointer to a list of HOTSRecord entries.
  210.  *               If fNewNode does not already exist in the list then it is
  211.  *               inserted at the head of the list.
  212.  * INTERFACE   : HOTSInsert(fNewNode)
  213.  *               fNewNode is a pointer to the HOTSRecord structure.
  214.  */
  215.  
  216. KKStatus HOTSInsert(fNewNode)
  217.     HOTSRecord fNewNode;
  218. {
  219.     KKStatus status;
  220.  
  221. #ifdef HOTSDBG
  222.     printf("entered HOTSInsert\n");
  223. #endif
  224.  
  225.     if (initflag) {
  226.  
  227.         /*Check for overflow. If no overflow try to insert in table*/
  228.         if (NoHOTSEntries <= HOTSLIMIT)  /*No overflow*/   {
  229.             status = InsertInTable(fNewNode, HashValue(fNewNode.LNN));
  230.             if (status == DSTS_Success)  {  
  231.  
  232.                 /*Update entries in table*/
  233.                 NoHOTSEntries += 1;
  234.  
  235. #ifdef HOTSDBG
  236.     printf( "inserted node no. %d NoHOTSEntries = %d\n", fNewNode.LNN, NoHOTSEntries);
  237. #endif
  238.             }
  239.             /*status obtained from InsertInTable returned*/
  240.                 return(status);
  241.         }
  242.         else  /*overflow*/  {
  243.  
  244. #ifdef HOTSDBG
  245.     printf( "table overflow\n");
  246. #endif
  247.  
  248.             return(DSTF_HOTSOvFlow);
  249.         }
  250.     }
  251.     else /*data structure not initialized*/  {
  252.  
  253. #ifdef HOTSDBG
  254.     printf( "HOTSCreate has not been called to create the HOTS table\n");
  255. #endif
  256.         return(DSTF_DSNotCreated);
  257.     }
  258. }
  259.  
  260.  
  261.  
  262. /*
  263.  * IN          : fNewEntry, fIndex 
  264.  * RETURNS     : KKStatus
  265.  * EFFECT      : If entry is not in table adds as the first element in the
  266.  *               chain of elements having the same hash value as this one.
  267.  *               Searches for fNewEntry in the list pointed to by the table
  268.  *               entry whose index is given by fIndex.  
  269.  *               If not found then adds it as the first entry in the list.
  270.  * INTERFACE   : InsertInTable(fNewEntry, fIndex)
  271.  *               fNewEntry is of type HOTSRecord and fIndex is an integer. 
  272.  */
  273.  
  274. static KKStatus InsertInTable(fNewEntry,fIndex)
  275.     HOTSRecord fNewEntry;
  276.     int fIndex;
  277. {
  278.     struct HOTStr *np;
  279.  
  280.     if ((np = LookUp(fNewEntry.LNN,fIndex)) == NULL)  {
  281.  
  282.         /*entry not in table. add it as first element in its chain*/
  283.  
  284. #ifdef HOTSDBG
  285.         printf( "Entry not in table. Add it as first element\n");
  286. #endif
  287.         np = (struct HOTStr *) malloc(sizeof(struct HOTStr));
  288.         if (np != NULL) {
  289.             np -> ThisEntry = fNewEntry;
  290.             np -> next = HOTSTable[fIndex];
  291.             HOTSTable[fIndex] = np;
  292. #ifdef HOTSDBG
  293.             printf( "New entry (%d, x%08x)\n", fNewEntry.LNN,
  294.                 &np -> ThisEntry);
  295. #endif
  296.             return(DSTS_Success);
  297.         }
  298.         else /*not enough memory got from malloc*/
  299.             return(DSTK_NoMemory);
  300.     }
  301.     else /*entry in table*/  {
  302.  
  303. #ifdef HOTSDBG
  304.         printf("entry in table already-returning\n");
  305. #endif
  306.  
  307.         return(DSTF_HOTSDupID);
  308.     }
  309. }
  310.  
  311.  
  312.  
  313.  
  314. /*
  315.  * IN          : fNewLNN, fIndex
  316.  * RETURNS     : A pointer to HOTStr if there is an entry for fNewUID and
  317.  *               NULL otherwise.
  318.  * EFFECT      : Checks whether an entry for fNewLNN exists in the list
  319.  *               pointed to by the table entry given by fIndex.  If so, 
  320.  *               a pointer to that entry is returned.  If not, returns
  321.  *               NULL.
  322.  * INTERFACE   : LookUp(fNewLNN, fIndex)
  323.  *               fNewLNN is of type NodeNum and fIndex is an integer.
  324.  */
  325.  
  326. static struct HOTStr *LookUp(fNewLNN, fIndex)        
  327.     NodeNum fNewLNN;
  328.     int fIndex;
  329. {
  330.     struct HOTStr *np;
  331.  
  332.     /*search the chain emanating from table[index]*/
  333.     for (np = HOTSTable[fIndex]; np != NULL; np = np -> next)
  334.         if (fNewLNN == np -> ThisEntry.LNN)
  335.           return(np);
  336.  
  337.     /*Entry not in the list*/
  338.     return(NULL);     /*not found*/
  339. }
  340.  
  341.  
  342.  
  343. /*
  344.  * IN       : fThisLNN
  345.  * RETURNS  : The hash value of the given node number
  346.  * INTERFACE: HashValue(fThisLNN)
  347.  *            fThisLNN is of type NodeNum
  348.  */
  349. /* Defined as a macro. 
  350. static int HashValue(fThisLNN)
  351.     NodeNum fThisLNN;
  352. {
  353.      return( fThisLNN & HOTSLAST );
  354. }
  355. */
  356.  
  357. /*
  358.  * IN       : fQueryLNN, fEntry
  359.  * OUT      : fEntry points to the HOTSRecord of fQueryLNN, if such
  360.  *            a HOTSRecord exists.
  361.  * RETURNS  : KKStatus
  362.  * EFFECT   : Searches the table for a HOTSRecord entry for the given LNN.  If
  363.  *            found then a pointer to the HOTSRecord is stored in fEntry.
  364.  *            In that case KKStatus is set to DSTS_Success.  If there is no
  365.  *            HOTSRecord entry for the given LNN then KKStatus is set to 
  366.  *            DSTF_HOTSSearchNoEntry.
  367.  * INTERFACE: HOTSSearch(fQueryLNN, fEntry)
  368.  *            fQueryLNN is of type NodeNum and fEntry is a pointer to
  369.  *            HOTSRecord.
  370.  */
  371.  
  372. KKStatus HOTSSearch(fQueryLNN, fEntry)
  373.     NodeNum fQueryLNN;
  374.     HOTSRecord *fEntry;
  375. {
  376.     int index;
  377.     struct HOTStr *ThisStr;
  378.  
  379. #ifdef HOTSDBG
  380.     printf("entering HOTSSearch\n");
  381. #endif
  382.     if (initflag) {
  383.         index = HashValue(fQueryLNN);
  384.  
  385.         if (HOTSTable[index] == NULL)  /*no chain*/ {
  386.  
  387. #ifdef HOTSDBG
  388.     printf( "no entry in table - returning\n");
  389. #endif
  390.  
  391.             return(DSTF_HOTSSearchNoEntry);
  392.         }
  393.         else   /*there is atleast one entry in the chain*/  {
  394.             ThisStr = LookUp(fQueryLNN, index);
  395.             if (ThisStr == NULL)  /*given LNN not in chain*/  {
  396.  
  397. #ifdef HOTSDBG
  398.     printf( "no entry in table - returning\n");
  399. #endif
  400.                 return(DSTF_HOTSSearchNoEntry);
  401.             }
  402.             else   /*given LNN in chain.  Get entry into fEntry*/  { 
  403.                 (*fEntry) = ThisStr -> ThisEntry;
  404.  
  405. #ifdef HOTSDBG
  406.     printf("got the entry (%d, x%08x) - returning\n", (*fEntry).LNN,
  407.         &ThisStr->ThisEntry);
  408. #endif
  409.  
  410.                 return(DSTS_Success);
  411.             }
  412.         }
  413.     }
  414.     else /*data structure not initialized*/  {
  415.  
  416. #ifdef HOTSDBG
  417.     printf( "HOTSCreate has not been called to create the HOTS table\n");
  418. #endif
  419.         return(DSTF_DSNotCreated);
  420.     }
  421. }
  422.  
  423.  
  424.  
  425. /*
  426.  * IN       : fQueryLNN, fEntryPtr
  427.  * OUT      : fEntryPtr points to the HOTSRecord of fQueryLNN, if such
  428.  *            a HOTSRecord exists.
  429.  * RETURNS  : KKStatus
  430.  * EFFECT   : Searches the table for a HOTSRecord entry for the given LNN.  If
  431.  *            found then a pointer to the address of the HOTSRecord is stored
  432.  *            in fEntryPtr. In that case KKStatus is set to DSTS_Success.
  433.  *            If there is no HOTSRecord entry for the given LNN then KKStatus
  434.  *            is set to DSTF_HOTSSearchNoEntry.
  435.  * INTERFACE: HOTSSearchPtr(fQueryLNN, fEntryPtr)
  436.  *            fQueryLNN is of type NodeNum and fEntryPtr is a pointer to
  437.  *            a HOTSRecord pointer.
  438.  */
  439.  
  440. KKStatus HOTSSearchPtr(fQueryLNN, fEntryPtr)
  441.     NodeNum fQueryLNN;
  442.     HOTSRecord **fEntryPtr;
  443. {
  444.     int index;
  445.     struct HOTStr *ThisStr;
  446.  
  447. #ifdef HOTSDBG
  448.     printf(">HOTSSearchPtr(%d, x)\n", fQueryLNN);
  449. #endif
  450.  
  451.     /* Check Cache. */
  452.     if ((fQueryLNN == CacheLNN) && CacheLNN) {
  453.         /* Cache hit. */
  454.         (*fEntryPtr) = CachePtr;
  455. #ifdef HOTSDBG
  456.         printf( " Cache hit (%d, x%08x)\n",
  457.             CacheLNN,  (*fEntryPtr));
  458. #endif
  459.         return DSTS_Success;
  460.     };
  461.  
  462.     if (initflag) {
  463.         index = HashValue(fQueryLNN);
  464.  
  465.         if (HOTSTable[index] == NULL)  /*no chain*/ {
  466.  
  467. #ifdef HOTSDBG
  468.     printf( "no entry in table - returning\n");
  469. #endif
  470.  
  471.             return(DSTF_HOTSSearchNoEntry);
  472.         }
  473.         else   /*there is atleast one entry in the chain*/  {
  474.             ThisStr = LookUp(fQueryLNN, index);
  475.             if (ThisStr == NULL)  /*given LNN not in chain*/  {
  476.  
  477. #ifdef HOTSDBG
  478.     printf( "no entry in table - returning\n");
  479. #endif
  480.                 return(DSTF_HOTSSearchNoEntry);
  481.             }
  482.             else   /*given LNN in chain.  Get entry into fEntryPtr*/  { 
  483.                 CachePtr = (*fEntryPtr) = &ThisStr -> ThisEntry;
  484.                 CacheLNN = fQueryLNN;
  485.  
  486. #ifdef HOTSDBG
  487.     printf("got the entry (%d, x%08x) - returning\n", CacheLNN,
  488.         CachePtr);
  489. #endif
  490.  
  491.                 return(DSTS_Success);
  492.             }
  493.         }
  494.     }
  495.     else /*data structure not initialized*/  {
  496.  
  497. #ifdef HOTSDBG
  498.     printf( "HOTSCreate has not been called to create the HOTS table\n");
  499. #endif
  500.         return(DSTF_DSNotCreated);
  501.     }
  502. }
  503.  
  504. /***********************************************************************
  505.  *                      Traverse the HOTS table.                       *
  506.  ***********************************************************************/
  507.  
  508.  
  509. HOTSRecord *HOTSTraverse( fIndex, fEntry)
  510.   integer       *fIndex;
  511.   struct HOTStr **fEntry;
  512. {
  513.   register int            index;
  514.   register struct HOTStr *entry;
  515.   
  516.   if (! initflag) {
  517.     *fEntry = NULL;
  518.     return ( NULL );
  519.   };
  520.  
  521.   index = *fIndex;
  522.   if ( (entry = *fEntry) != NULL )
  523.     entry = entry->next;
  524.   if ( entry == NULL )
  525.     for ( index = index+1; index < HOTSIZE; index++ )
  526.       if ( (entry = HOTSTable[index]) != NULL )
  527.         break;
  528.   if ( entry == NULL ) {
  529.     return ( NULL );
  530.     }
  531.   else
  532.     {   *fIndex = index;
  533.         *fEntry = entry;
  534.         return ( &entry->ThisEntry );
  535.     }
  536. }
  537.  
  538.  
  539.  
  540. /*
  541.  * IN       : fNewData
  542.  * RETURNS  : KKSTATUS
  543.  * EFFECT   : The HOTSRecord entry in the table for the LNN in fNewData is
  544.  *            replaced.  If no entry exists for the given LNN then KKStatus
  545.  *            is set to DSTF_HOTSReplaceNoEntry.
  546.  * INTERFACE: HOTSReplace(fNewData)
  547.  *            Here fNewData is of type HOTSRecord.
  548.  */
  549.  
  550. KKStatus HOTSReplace(fNewData)
  551.     HOTSRecord fNewData;
  552. {
  553.     int index;
  554.     struct HOTStr *ThisStr;
  555.  
  556. #ifdef HOTSDBG
  557.     printf( "entering HOTSReplace\n");
  558. #endif
  559.     /* Invalidate cache. */
  560.     CacheLNN = 0;
  561.     if (initflag) { 
  562.         index = HashValue(fNewData.LNN);
  563.         if (HOTSTable[index] == NULL)  /*no chain*/  {
  564.  
  565. #ifdef HOTSDBG
  566.     printf( "entry not in table - returning\n");
  567. #endif
  568.  
  569.             return(DSTF_HOTSReplaceNoEntry);
  570.         }
  571.         else   /*there is at least one entry in the chain*/   {
  572.             ThisStr = LookUp(fNewData.LNN, index);
  573.             if (ThisStr == NULL)  /*given LNN not in chain*/  {
  574.  
  575. #ifdef HOTSDBG
  576.     printf( "entry not in table - returning\n");
  577. #endif
  578.  
  579.                 return(DSTF_HOTSReplaceNoEntry);
  580.             }
  581.             else   /*given LNN in chain.  replace entry by fNewData*/   { 
  582.                 ThisStr -> ThisEntry = fNewData;
  583.  
  584. #ifdef HOTSDBG
  585.     printf("replaced entry - returning\n");
  586. #endif
  587.  
  588.                 return(DSTS_Success);
  589.             }
  590.         }
  591.     }
  592.     else /*data structure not initialized*/ {
  593.  
  594. #ifdef HOTSDBG
  595.     printf( "HOTSCreate has not been called to create the HOTS table\n");
  596. #endif
  597.         return(DSTF_DSNotCreated);
  598.     }
  599. }
  600.  
  601.  
  602.  
  603. /*
  604.  * IN        : fLNN
  605.  * RETURNS   : KKSTATUS
  606.  * EFFECT    : Deletes the HOTSRecord entry associated with fLNN from the table.
  607.  * INTERFACE : HOTSDelete(fLNN)
  608.  *             fLNN is of type NodeNum
  609.  */
  610.  
  611. KKStatus HOTSDelete(fLNN)
  612.     NodeNum fLNN;
  613. {
  614.     int index;
  615.     struct HOTStr *prev, *crnt;
  616.  
  617. #ifdef HOTSDBG
  618.     printf( "entering HOTSDelete\n");
  619. #endif
  620.     /* Invalidate Cache */
  621.     CacheLNN = 0;
  622.     if (initflag) {
  623.         index = HashValue(fLNN);
  624.  
  625.         if (HOTSTable[index] == NULL)  /*no chain*/ {
  626.  
  627. #ifdef HOTSDBG
  628.     printf( "entry not in table - returning\n");
  629. #endif
  630.  
  631.             return(DSTF_HOTSDeleteNoEntry);
  632.         }
  633.         else  /*there is atleast one entry in the chain*/
  634.             if (HOTSTable[index] -> ThisEntry.LNN == fLNN)  {
  635.  
  636. #ifdef HOTSDBG
  637.     printf( "the first entry in the chain to be deleted");
  638. #endif
  639.  
  640.                 /*the first entry in the chain to be deleted*/
  641.                 crnt = HOTSTable[index];
  642.                 HOTSTable[index] = HOTSTable[index] -> next;          
  643.                 free((char *)crnt);
  644.  
  645. #ifdef HOTSDBG
  646.     printf( " - returning after deleting\n");
  647. #endif
  648.  
  649.                 NoHOTSEntries--;
  650.                 return(DSTS_Success);
  651.             }
  652.             else {  
  653.  
  654.                 /*the first entry does not match.  Check other entries in chain*/
  655.                 prev = HOTSTable[index];
  656.                 for (crnt = HOTSTable[index] -> next; crnt != NULL; 
  657.                     prev = crnt, crnt = crnt -> next)
  658.                     if (crnt -> ThisEntry.LNN == fLNN)  {
  659.  
  660.                         /*this entry to be deleted; release storage*/
  661.                         prev -> next = crnt -> next;
  662.                         free((char *)crnt);
  663.  
  664. #ifdef HOTSDBG
  665.     printf("located and deleted the entry - returning\n");
  666. #endif
  667.  
  668.                         NoHOTSEntries--;
  669.                         return(DSTS_Success);
  670.                     }
  671.  
  672. #ifdef HOTSDBG
  673.     printf( "the entry not present - returning\n");
  674. #endif
  675.  
  676.                 return(DSTF_HOTSDeleteNoEntry);
  677.             }
  678.     }
  679.     else /*data structure not initialized*/ {
  680.  
  681. #ifdef HOTSDBG
  682.     printf( "HOTSCreate has not been called to create the HOTS table\n");
  683. #endif
  684.         return(DSTF_DSNotCreated);
  685.     }
  686. }
  687.  
  688. #ifdef xxxPRINTHOTSTABLExxx
  689. /*
  690.  * IN        : fFile
  691.  * RETURNS   : KKStatus
  692.  * EFFECT    : Writes all the HOTS records in the HOTS table onto the file
  693.  *             pointed to by fFile.
  694.  * INTERFACE : PrintHOTSTable(fFile)
  695.  *             fFile is a file pointer.
  696.  */
  697. KKStatus PrintHOTSTable(fFile)
  698. FILE *fFile;
  699. {
  700.   int i;
  701.   if (initflag) {
  702. #ifdef xsimul
  703.     fprintf(fFile, "The contents of the HOTS table:\n");
  704.     for (i = 0; i < HOTSIZE; i++)  
  705.       if (HOTSTable[i] != NULL) 
  706.     PrintHOTStr(fFile, HOTSTable[i]);
  707. #else
  708.     printf("unix would print HOTS table to a file here\n")
  709. #endif
  710.     return(DSTS_Success);
  711.   } else { /*HOTS table not initialized*/
  712.  
  713. #ifdef HOTSDBG
  714.     printf( "HOTSCreate has not been called to create the HOTS table\n");
  715. #endif
  716.     return(DSTF_DSNotCreated);
  717.   }
  718. }
  719.  
  720.  
  721. /*
  722.  * IN        : fFile, fHOTStr
  723.  * EFFECT    : Writes all the HOTSRecords which hashed to the same index onto 
  724.  *             the file pointed to by fFile.
  725.  * INTERFACE : PrintHOTStr(fFile, fHOTStr)
  726.  *             fFile is a file pointer and fHOTStr is a pointer to HOTStr.
  727.  */
  728. static PrintHOTStr(fFile, fHOTStr)
  729.     FILE *fFile;
  730.     struct HOTStr *fHOTStr;
  731. {
  732.     register struct HOTStr *np;
  733. #ifdef xsimul
  734.     for (np = fHOTStr; np != NULL; np = np -> next)
  735.         PrintHOTS(fFile, np -> ThisEntry);
  736. #endif
  737. }
  738.  
  739.  
  740.  
  741. /*
  742.  * IN           : fFile, fHR
  743.  * RETURNS      : KKStatus
  744.  * EFFECT       : Writes entries of a given HOTSRecord onto the file pointed
  745.  *                to by fFile.
  746.  * DEFICIENCIES : Not all entries of the HOTS record are written out.
  747.  * INTERFACE    : PrintHOTS(fFile, fHR)
  748.  *                fFile is a file pointer and fHR is of type HOTSRecord
  749.  */
  750. KKStatus PrintHOTS(fFile, fHR)
  751.     FILE *fFile;
  752.     HOTSRecord fHR;
  753. {
  754. #ifdef xsimul
  755.     fprintf(fFile, " Logical node number : ");
  756.     PrintNodeNum(fFile, fHR.LNN);
  757.     fprintf(fFile, " EtherNetAddress : ");
  758.     PrintEtherNetAddress(fFile, fHR.EtherAddr);
  759.     fprintf(fFile, " NodeStatus : ");
  760.     PrintNodeStatus(fFile, fHR.NodeStat);
  761.     fprintf(fFile, " Last Message TimeStamp : ");
  762.     PrintTS(fFile, fHR.LastMsgTs);
  763.     fprintf(fFile, " Node Characteristics as a 32-bit integer : ");
  764.     PrintNodeCharacteristics(fFile, fHR.NodeCharac);
  765.     if (fHR.NodeIsLocal)
  766.         fprintf(fFile, " Local\n");
  767.     else
  768.         fprintf(fFile, " Not local\n");
  769.     fprintf(fFile, " Port = ");
  770.     PrintEdenPort(fFile, fHR.NodeNetPort);
  771.     fprintf(fFile,
  772.         "AckExp    NxtTSend  NxtSeqNo        LatestAck MsgExp    TooFar\n");
  773.     fprintf(fFile, "%5d %9d %9d       %9d %9d %9d\n", fHR.AckExpected,
  774.         fHR.NextMsgToSend, fHR.NextSeqNo, fHR.LatestAck, fHR.MsgExpected,
  775.         fHR.TooFar);
  776.     fprintf(fFile, "SWSize =  %d,    OutOfOrder Count = %d\n",
  777.         fHR.SendWindowSize, fHR.OutOfOrderCount);
  778.     if (fHR.Timed)
  779.         fprintf(fFile, "Timed     AckTimer = %d, MsgTimer = %d",
  780.             fHR.AckTimerCount, fHR.MsgTimerCount);
  781.     else
  782.         fprintf(fFile, "Not Timed.");
  783.     if (fHR.NakSent)
  784.         fprintf(fFile, "   NAK has been sent.\n");
  785.     else
  786.         fprintf(fFile, "   No NAK has been sent.\n");
  787.     fprintf(fFile, "ToSendPtr  %08x  SentPtr  %08x\n", fHR.ToSendPtr,
  788.         fHR.SentPtr);
  789.     fprintf(fFile, "Statistics\n");
  790.     fprintf(fFile,
  791.         "ReTran NAKSen NAKRcv MsgDrp ACKSen ACKRcv MsgDlv MsgAcp\n");
  792.     fprintf(fFile, "%5d %6d %6d %6d %6d %6d %6d %6d\n", fHR.RetransCount,
  793.         fHR.NAKsSent, fHR.NAKsRecv, fHR.MsgDropped, fHR.ACKsSent,
  794.         fHR.ACKsRecv, fHR.MsgDelivered, fHR.MsgAccepted);
  795.     fprintf(fFile, "\n\n");
  796.     (void) fflush(fFile);
  797. #endif
  798.     return(DSTS_Success);
  799. }
  800.  
  801. #endif xxxPRINTHOTSTABLExxx
  802.  
  803.  
  804. /*  Snapshot auxiliarry procedure to print a single entry. */
  805.  
  806. void SnapHOTSElem(fHR)
  807.     HOTSRecord fHR;
  808. {
  809.     KMDPrint("Logical node number : %3d of %.15s  %s\n", (int) fHR.LNN,
  810.         4+ctime(&fHR.NodeIncarnationId), NSStatus(fHR.NodeStat));
  811.     KMDPrint("EtherNetAddress     : %s   %-7.7s at %-8.8s\n", 
  812.         inet_ntoa(fHR.EtherAddr.sin_addr),
  813.         fHR.NodeIsLocal ? "Local" : "Remote",
  814.         mGetHostName(&(fHR.EtherAddr)));
  815.     KMDPrint("Last Msg Time       : %-24.24s.\n", ctime(&fHR.LastMsgTs));
  816.     /* KMDPrint("Node Characteristics: 0x%08x (%s)\n",
  817.         fHR.NodeCharac, NodeKind(&fHR) ); */
  818.     KMDPrint(
  819.         "AckExp    NxtTSend  NxtSeqNo        LatestAck MsgExp    TooFar\n");
  820.     KMDPrint("%5d %9d %9d       %9d %9d %9d\n", fHR.AckExpected,
  821.         fHR.NextMsgToSend, fHR.NextSeqNo, fHR.LatestAck, fHR.MsgExpected,
  822.         fHR.TooFar);
  823.     KMDPrint("SendWindowSize %2d,  OutOfOrder  %d,  %sNAK sent\n",
  824.         fHR.SendWindowSize, fHR.OutOfOrderCount, fHR.NakSent ? "" : "No ");
  825.     if (fHR.Timed)
  826.         KMDPrint("Timed     AckTimer = %d ticks, MsgTimer = %d ticks.\n",
  827.             fHR.AckTimerCount, fHR.MsgTimerCount);
  828.     else
  829.         KMDPrint("No activity  pending - not timed.\n");
  830.     KMDPrint("First flow-controlled msg %s been sent from me to this node.\n",
  831.          fHR.FirstFCMsgSent ? "has" : "has not");
  832.     if (fHR.FirstFCMsgSent) {
  833.     KMDPrint("FCM sent, ToSendPtr %08x  SentPtr %08x\n", fHR.ToSendPtr,
  834.         fHR.SentPtr);
  835.     } else KMDPrint("No message sent to this node.\n");
  836.     KMDPrint("Statistics for Ethernet communication protocol\n");
  837.     KMDPrint("ReTran NAKSen NAKRcv MsgDrp ACKSen ACKRcv MsgDlv MsgAcp\n");
  838.     KMDPrint("%5d %6d %6d %6d %6d %6d %6d %6d\n", fHR.RetransCount,
  839.         fHR.NAKsSent, fHR.NAKsRecv, fHR.MsgDropped, fHR.ACKsSent,
  840.         fHR.ACKsRecv, fHR.MsgDelivered, fHR.MsgAccepted);
  841.     KMDPrint("\n");
  842. }
  843.  
  844.  
  845. /* Snapshot routine to dump the HOTS table in a readable format.    */
  846. /* If given a non-zero parameter only the specified table entry is  */
  847. /* printed.                                                         */
  848. /* Eric Jul, 1984-05-20                                             */
  849.  
  850. void HOTSDump(fLNN)
  851. int     fLNN;
  852. {
  853.     int i;
  854.     register struct HOTStr *np;
  855.     time_t theTime;
  856.     
  857.     theTime = time((time_t *) 0);
  858.  
  859.     KMDPrint("Dump of HOTS Table residing in LNN %d at %s\n", GetLNN(),
  860.         ctime(&theTime));
  861.  
  862.     for (i=0; i < HOTSIZE; i++)
  863.         for(np = HOTSTable[i]; np != NULL; np = np -> next)
  864.             if ( (! fLNN) || (fLNN == np->ThisEntry.LNN) )
  865.                 SnapHOTSElem(np -> ThisEntry);
  866. }
  867.  
  868.  
  869. /* Prints the HOTS table in a one line per entry format. */
  870.  
  871. void Whatisup()
  872. {
  873.     register int i;
  874.     register struct HOTStr *np;
  875.     time_t   theTime = time((time_t *) 0);
  876.     time_t   tmp;
  877.     char     incarnationTimeString[20];
  878.  
  879.     KMDPrint("Emerald network according to node %d on %s", GetLNN(),
  880.         ctime(&theTime));
  881.     KMDPrint(" LNN  Incarnation      Physical     State      Last state change\n");
  882.     KMDPrint(" ---------------------------------------------------------------\n");
  883.  
  884.     for (i=0; i < HOTSIZE; i++)
  885.         for(np = HOTSTable[i]; np != NULL; np = np -> next) {
  886.             tmp = np->ThisEntry.LastMsgTs;
  887.             (void) sprintf(incarnationTimeString, "%.15s",
  888.             4+ctime(&np->ThisEntry.NodeIncarnationId));
  889.             KMDPrint("%4d  %.15s  %-11.11s  %-8.8s   %-15.15s\n",
  890.                     np->ThisEntry.LNN,
  891.             incarnationTimeString,
  892.                     mGetHostName(&(np->ThisEntry.EtherAddr)),
  893.                     NSStatus(np->ThisEntry.NodeStat),
  894.                     4+ctime(&tmp));
  895.         }
  896. }
  897.